unit outputinvoiceselement;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  ComCtrls, Buttons, StdCtrls, DbCtrls, Grids;

type

  { TfrmOutputInvoicesElement }

  TfrmOutputInvoicesElement = class(TForm)
    btnGoodsCancel: TBitBtn;
    btnPrint: TBitBtn;
    btnClose: TBitBtn;
    btnCounterPartiesSelect: TBitBtn;
    btnGoodsDelete: TBitBtn;
    btnGoodsAdd: TBitBtn;
    btnGoodsSave: TBitBtn;
    btnSave: TBitBtn;
    btnStoreHousesSelect: TBitBtn;
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    lblquantity: TLabel;
    lblsum: TLabel;
    lblEdtCounterParty: TLabeledEdit;
    lblEdtStoreHouse: TLabeledEdit;
    PC: TPageControl;
    rgPriceType: TRadioGroup;
    StringGridGoods: TStringGrid;
    TSGoods: TTabSheet;
    procedure btnCounterPartiesSelectClick(Sender: TObject);
    procedure btnGoodsCancelClick(Sender: TObject);
    procedure btnGoodsDeleteClick(Sender: TObject);
    procedure btnGoodsAddClick(Sender: TObject);
    procedure btnGoodsSaveClick(Sender: TObject);
    procedure btnPrintClick(Sender: TObject);
    procedure btnSaveClick(Sender: TObject);
    procedure btnStoreHousesSelectClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
    procedure FormShow(Sender: TObject);
    procedure refreshListOfGoods;
    procedure checkErrors();
    procedure rgPriceTypeSelectionChanged(Sender: TObject);
    procedure StringGridGoodsDblClick(Sender: TObject);
    procedure updateAllCount;
    procedure StringGridGoodsKeyPress(Sender: TObject; var Key: char);
    procedure StringGridGoodsSelectCell(Sender: TObject; aCol, aRow: Integer;
      var CanSelect: Boolean);
    procedure StringGridGoodsValidateEntry(sender: TObject; aCol,
      aRow: Integer; const OldValue: string; var NewValue: String);
  private
    { private declarations }
  public
    { public declarations }
    ginvoiceid:Integer;
    invoiceIsNew:Boolean;
  end;

var
  frmOutputInvoicesElement: TfrmOutputInvoicesElement;
  invoiceChanged:Boolean=False;
  goodsChanged:Boolean=False;
  goodsEditMode:Boolean=False;
implementation

{$R *.lfm}

{ TfrmOutputInvoicesElement }

uses main, nomenclatureselect,counterpartiesselect,storehouseselect;

procedure TfrmOutputInvoicesElement.updateAllCount;
var
  i,quantity,storeHousesGoodQuantity,oldCount:Integer;
  sum:Currency;
begin
  ///////////Update Summ and Count on the label | and check all entered data
  sum := 0;
  quantity := 0;
  for i:=1 to StringGridGoods.RowCount-1 do begin
    if (StringGridGoods.Cells[2,i] = EmptyStr) OR (StringGridGoods.Cells[3,i] = EmptyStr) OR (StringGridGoods.Cells[5,i] = EmptyStr) then begin
      btnGoodsSave.Enabled := False;
    end else begin
      btnGoodsSave.Enabled := True;
      sum := sum +(StrToInt(StringGridGoods.Cells[3,i]) * StrToCurr(StringGridGoods.Cells[5,i]));
      quantity := quantity + StrToInt(StringGridGoods.Cells[3,i]);
    end;
  end;
  lblsum.Caption := CurrToStr(sum);
  lblquantity.Caption := IntToStr(quantity);
end;
procedure TfrmOutputInvoicesElement.refreshListOfGoods;
var
  i,quantity:Integer;
  sum:Currency;
begin
  sum:=0;
  quantity:=0;
  StringGridGoods.Clear;
  StringGridGoods.RowCount:=1;
  FrmMain.DSOutPutGoodsView.DataSet.Filter:='invoiceid='+IntToStr(ginvoiceid);
  FrmMain.DSOutPutGoodsView.DataSet.Filtered:=True;
  FrmMain.DSOutPutGoodsView.DataSet.Refresh;
  StringGridGoods.RowCount:=FrmMain.DSOutPutGoodsView.DataSet.RecordCount+1;
  FrmMain.ZQOutPutGoodsView.First;
  for i:=1 to FrmMain.DSOutPutGoodsView.DataSet.RecordCount do begin
    StringGridGoods.Cells[1,i]:=FrmMain.DSOutPutGoodsView.DataSet.FieldByName('id').AsString;
    StringGridGoods.Cells[2,i]:=FrmMain.DSOutPutGoodsView.DataSet.FieldByName('title').AsString;
    StringGridGoods.Cells[3,i]:=FrmMain.DSOutPutGoodsView.DataSet.FieldByName('quantity').AsString;
    StringGridGoods.Cells[4,i]:=FrmMain.DSOutPutGoodsView.DataSet.FieldByName('typeofprice').AsString;
    StringGridGoods.Cells[5,i]:=CurrToStr(FrmMain.DSOutPutGoodsView.DataSet.FieldByName('price').AsCurrency/FrmMain.DSOutPutGoodsView.DataSet.FieldByName('quantity').AsInteger);
    StringGridGoods.Cells[6,i]:=FrmMain.DSOutPutGoodsView.DataSet.FieldByName('price').AsString;
    StringGridGoods.Cells[7,i]:=FrmMain.DSOutPutGoodsView.DataSet.FieldByName('nomenclatureid').AsString;
    //ShowMessage(IntToStr(FrmMain.DSComingGoodsView.DataSet.RecNo)+ ' ' + FrmMain.DSOutPutGoodsView.DataSet.FieldByName('id').AsString);
    sum:=sum+FrmMain.DSOutPutGoodsView.DataSet.FieldByName('price').AsCurrency;
    quantity:=quantity+FrmMain.DSOutPutGoodsView.DataSet.FieldByName('quantity').AsInteger;
    FrmMain.ZQOutPutGoodsView.Next;
  end;
  lblsum.Caption:=CurrToStr(sum);
  lblquantity.Caption:=IntToStr(quantity);
end;

procedure TfrmOutputInvoicesElement.checkErrors();
begin
  //////////////////////////////////////////
  if (lblEdtCounterParty.Text=EmptyStr) OR (lblEdtStoreHouse.Text=EmptyStr) then begin
    btnSave.Enabled:=False;
  end else begin
    btnSave.Enabled:=True;
  end;
  //////////////////////////////////////////
  if (goodsEditMode) then begin
    rgPriceType.Enabled:=True;
    btnGoodsAdd.Enabled:=False;
    btnGoodsSave.Enabled:=True;
    btnGoodsCancel.Enabled:=True;
    btnGoodsDelete.Enabled:=False;
    btnSave.Enabled:=False;
    btnClose.Enabled:=False;
    btnPrint.Enabled:=False;
  end else begin
    rgPriceType.Enabled:=False;
    btnGoodsAdd.Enabled:=True;
    btnGoodsSave.Enabled:=False;
    btnGoodsCancel.Enabled:=False;
    btnGoodsDelete.Enabled:=True;
    btnSave.Enabled:=True;
    btnClose.Enabled:=True;
    btnPrint.Enabled:=True;
  end;
  //////////////////////////////////////////
  if NOT invoiceIsNew AND NOT invoiceChanged then begin
    btnSave.Enabled:=False;
    btnCounterPartiesSelect.Enabled:=False;
    btnStoreHousesSelect.Enabled:=False;
  end;
  //////////////////////////////////////////
  if invoiceIsNew then begin
    btnCounterPartiesSelect.Enabled:=True;
    btnStoreHousesSelect.Enabled:=True;
  end else begin
    btnCounterPartiesSelect.Enabled:=False;
    btnStoreHousesSelect.Enabled:=False;
  end;
  //////////////////////////////////////////
  if invoiceIsNew OR invoiceChanged OR goodsChanged then begin
    btnSave.Enabled:=True;
    btnPrint.Enabled:=False;
  end;
  //////////////////////////////////////////
  if (StringGridGoods.RowCount=1) then begin
    btnGoodsDelete.Enabled:=False;
  end;
  //////////////////////////////////////////
  if (lblEdtCounterParty.Text=EmptyStr) OR (lblEdtStoreHouse.Text=EmptyStr) then begin
    btnSave.Enabled:=False;
  end;
end;

procedure TfrmOutputInvoicesElement.rgPriceTypeSelectionChanged(Sender: TObject);
begin
  StringGridGoods.Cells[4,StringGridGoods.Row]:=IntToStr(rgPriceType.ItemIndex+1);
end;

procedure TfrmOutputInvoicesElement.StringGridGoodsDblClick(Sender: TObject);
begin
  if ((StringGridGoods.SelectedColumn.Title.Caption = 'Номенклатура') AND (StringGridGoods.Cells[1,StringGridGoods.Row]=EmptyStr)) then begin
    FrmMain.clearSelect;
    frmNomenclatureSelect.ShowModal;
    StringGridGoods.Cells[2,StringGridGoods.Row]:=FrmMain.nomenclatureSelectedTitle;
    StringGridGoods.Cells[7,StringGridGoods.Row]:=IntToStr(FrmMain.nomenclatureSelectedId);
  end;
end;

procedure TfrmOutputInvoicesElement.StringGridGoodsKeyPress(Sender: TObject;
  var Key: char);
begin
  if StringGridGoods.SelectedColumn.Title.Caption = 'Кількість' then begin
    FrmMain.KeyVerifyInt(Sender,Key);
  end;
  if StringGridGoods.SelectedColumn.Title.Caption = 'Сума' then begin
    FrmMain.KeyVerifyFloat(Sender,Key);
  end;
end;

procedure TfrmOutputInvoicesElement.StringGridGoodsSelectCell(Sender: TObject;
  aCol, aRow: Integer; var CanSelect: Boolean);
begin
  if goodsEditMode then begin
    if StringGridGoods.Row<>aRow then begin
    CanSelect:=False;
    end else begin
    CanSelect:=True;
    end;
  end;
end;

procedure TfrmOutputInvoicesElement.StringGridGoodsValidateEntry(
  sender: TObject; aCol, aRow: Integer; const OldValue: string;
  var NewValue: String);
var
  i,storeHousesGoodQuantity,oldCount:Integer;
  priceType:Integer;
  MarkUpL:Currency;
begin
  //Save previos count number
  if ((aCol=3) AND (StringGridGoods.Cells[1,aRow]<>EmptyStr) AND (StringGridGoods.Cells[8,aRow]=EmptyStr) AND (OldValue<>NewValue)) then begin
    StringGridGoods.Cells[8,aRow] := OldValue;
  end;
  storeHousesGoodQuantity := 0;
  if (StringGridGoods.Cells[7,aRow]<>EmptyStr) then begin
     storeHousesGoodQuantity:=FrmMain.tableQuantity('nomenclatureonstorehouses','nomenclatureid='+StringGridGoods.Cells[7,aRow]+' AND storehouseid='+IntToStr(FrmMain.storeHouseSelectedId));
  end;
  if StringGridGoods.Cells[8,aRow]=EmptyStr then begin
    oldCount := 0;
  end else begin
    oldCount := StrToInt(StringGridGoods.Cells[8,aRow]);
  end;
  if ((aCol=3) AND (NewValue<>EmptyStr) AND ((storeHousesGoodQuantity-abs(StrToInt(StringGridGoods.Cells[3,aRow])))+oldCount<0)) then begin
    ShowMessage('Невистачає товару на складі'+#13+'На складі '+IntToStr(storeHousesGoodQuantity)+' одиниць товару');
    FrmMain.history('Вихідна накладна','Спроба встановити невідповідну кількість товару'+#13+'На складі '+IntToStr(storeHousesGoodQuantity)+' одиниць товару');
    NewValue := OldValue;
  end;
  if ((aCol=3) AND (StringGridGoods.Cells[1,aRow] = EmptyStr) AND (StringGridGoods.Cells[3,aRow]<>EmptyStr)  AND (NewValue<>EmptyStr)) then begin
    case StrToInt(StringGridGoods.Cells[4,aRow])-1 of
       0: priceType := frmNomenclatureSelect.priceretail;
       1: priceType := frmNomenclatureSelect.pricesmallwholesale;
       2: priceType := frmNomenclatureSelect.pricebigwholesale;
    end;
    MarkUpL := ((StrToInt(NewValue) * frmNomenclatureSelect.price) * ((priceType * 0.01) + 1)) * FrmMain.ExchangeRate;
    StringGridGoods.Cells[5,StringGridGoods.Row] := CurrToStr(MarkUpL/StrToInt(NewValue));
    StringGridGoods.Cells[6,StringGridGoods.Row] := CurrToStr(MarkUpL);
  end;
  updateAllCount;
end;

procedure TfrmOutputInvoicesElement.FormShow(Sender: TObject);
begin
  if invoiceIsNew then begin
    lblEdtCounterParty.Clear;
    lblEdtStoreHouse.Clear;
    StringGridGoods.Clear;
    StringGridGoods.RowCount:=1;
    rgPriceType.ItemIndex:=0;
    lblsum.Caption:='';
    lblquantity.Caption:='';
  end else begin
    refreshListOfGoods;
  end;
  checkErrors();
end;

procedure TfrmOutputInvoicesElement.FormCloseQuery(Sender: TObject;
  var CanClose: boolean);
var
  res:Integer;
begin
  if invoiceIsNew OR goodsChanged OR invoiceChanged then begin
    res:=MessageDlg('','Закрити без збереження данних?',mtConfirmation,mbYesNo,0);
    if (res=mrYes) then begin
      if (invoiceIsNew) then begin
        invoiceIsNew:=False;
      end;
      invoiceChanged:=False;
      goodsEditMode:=False;
      FrmMain.history('Вихідна накладна','Вихід без збереження');
    end else begin
        CanClose:=False;
    end;
  end;
  FrmMain.DSOutPutInvoices.DataSet.Refresh;
end;

procedure TfrmOutputInvoicesElement.btnCounterPartiesSelectClick(Sender: TObject
  );
begin
  frmCounterPartiesSelect.ShowModal;
  lblEdtCounterParty.Text:=FrmMain.counterPartieSelectedTitle;
  invoiceChanged:=True;
  checkErrors();
end;

procedure TfrmOutputInvoicesElement.btnGoodsCancelClick(Sender: TObject);
begin
  StringGridGoods.DeleteRow(StringGridGoods.Row);
  goodsEditMode:=False;
  checkErrors();
end;

procedure TfrmOutputInvoicesElement.btnGoodsDeleteClick(Sender: TObject);
var
  res:Integer;
begin
  res:=MessageDlg('','Видалити запис?',mtConfirmation,mbYesNo,0);
  if (res=mrYes) then begin
    if ((invoiceIsNew) OR (StringGridGoods.Cells[1,StringGridGoods.Row]=EmptyStr)) then begin
      StringGridGoods.DeleteRow(StringGridGoods.Row);
    end else begin
      FrmMain.ZQuery.SQL.Text:='DELETE FROM outputgoods WHERE id='+StringGridGoods.Cells[1,StringGridGoods.Row];
      FrmMain.ZQuery.ExecSQL;
      FrmMain.updateStoreHousesGoodsCount(StringGridGoods.Cells[3,StringGridGoods.Row],IntToStr(FrmMain.storeHouseSelectedId),StringGridGoods.Cells[7,StringGridGoods.Row]);
      StringGridGoods.DeleteRow(StringGridGoods.Row);
      FrmMain.DSComingGoodsView.DataSet.Refresh;
      updateAllCount;
      { TODO 6 : Виправити перевірку }
      btnGoodsSave.Enabled := False;
    end;
    checkErrors();
  end;
end;

procedure TfrmOutputInvoicesElement.btnGoodsAddClick(Sender: TObject);
begin
  StringGridGoods.RowCount:=StringGridGoods.RowCount+1;
  StringGridGoods.Row:=StringGridGoods.RowCount;
  StringGridGoods.Cells[4,StringGridGoods.Row]:=IntToStr(rgPriceType.ItemIndex+1);
  goodsEditMode:=True;
  checkErrors();
  btnGoodsSave.Enabled:=False;
  btnSave.Enabled:=False;
end;

procedure TfrmOutputInvoicesElement.btnGoodsSaveClick(Sender: TObject);
begin
  goodsChanged:=True;
  goodsEditMode:=False;
  checkErrors();
end;

procedure TfrmOutputInvoicesElement.btnPrintClick(Sender: TObject);
begin
  FrmMain.frDBDataSet.DataSource:=FrmMain.DSOutPutGoodsView;
  FrmMain.purveyor:=FrmMain.entrepreneur;
  FrmMain.recipient:=lblEdtCounterParty.Text;
  FrmMain.invoiceID:=IntToStr(ginvoiceid);
  FrmMain.frReport.LoadFromFile(FrmMain.program_dir+'reports\outputinvoice.lrf');
  FrmMain.frReport.ShowReport;
end;

procedure TfrmOutputInvoicesElement.btnSaveClick(Sender: TObject);
var
  i:Integer;
  quantity:String;
begin
  if invoiceIsNew then begin
    FrmMain.ZQuery.SQL.Text:='INSERT INTO outputofinvoicesongoods VALUES(NULL,CURRENT_TIMESTAMP,'+IntToStr(FrmMain.counterPartieSelectedId)+','+IntToStr(FrmMain.storeHouseSelectedId)+')';
    FrmMain.ZQuery.ExecSQL;
    ginvoiceid:=FrmMain.LastInsertID('outputofinvoicesongoods');
  end else begin
    if invoiceChanged then begin
      FrmMain.ZQuery.SQL.Text:='UPDATE outputofinvoicesongoods SET counterpartyid='+IntToStr(FrmMain.counterPartieSelectedId)+',storehouse='+IntToStr(FrmMain.storeHouseSelectedId)+' WHERE id='+IntToStr(ginvoiceid);
      FrmMain.ZQuery.ExecSQL;
    end;
  end;

  if goodsChanged then begin
    for i:=1 to StringGridGoods.RowCount-1 do begin
      if StringGridGoods.Cells[1,i]=EmptyStr then begin
        FrmMain.ZQuery.SQL.Text:='INSERT INTO outputgoods VALUES(NULL,'+IntToStr(ginvoiceid)+','+StringGridGoods.Cells[7,i]+','+StringGridGoods.Cells[4,i]+','+StringGridGoods.Cells[3,i]+','+StringReplace(StringGridGoods.Cells[6,i], ',', '.',[rfReplaceAll])+')';
        FrmMain.ZQuery.ExecSQL;
      end else begin
         FrmMain.ZQuery.SQL.Text:='UPDATE outputgoods SET typeofprice='+StringGridGoods.Cells[4,i]+',quantity='+StringGridGoods.Cells[3,i]+',price='+StringReplace(StringGridGoods.Cells[6,i], ',', '.',[rfReplaceAll])+' WHERE id='+StringGridGoods.Cells[1,i];
         FrmMain.ZQuery.ExecSQL;
      end;
      quantity:='0';
      //////////////////////////////////////////////////
      if (StringGridGoods.Cells[1,i]=EmptyStr) then begin
         FrmMain.updateStoreHousesGoodsCount('-'+StringGridGoods.Cells[3,i],IntToStr(FrmMain.storeHouseSelectedId),StringGridGoods.Cells[7,i]);
      end;
      /////////////////Update count of goods if changed, in nomenclature and storehouse///////////////////
      if (((StringGridGoods.Cells[1,i]<>EmptyStr)) AND (StringGridGoods.Cells[8,i]<>EmptyStr) AND (StringGridGoods.Cells[3,i]<>StringGridGoods.Cells[8,i])) then begin
        if StrToInt(StringGridGoods.Cells[8,i])<StrToInt(StringGridGoods.Cells[3,i]) then begin
          quantity:='-'+IntToStr(StrToInt(StringGridGoods.Cells[3,i])-StrToInt(StringGridGoods.Cells[8,i]));
        end else begin
          quantity:=IntToStr(StrToInt(StringGridGoods.Cells[8,i])-StrToInt(StringGridGoods.Cells[3,i]));
        end;
        if StrToInt(StringGridGoods.Cells[8,i])=StrToInt(StringGridGoods.Cells[3,i]) then begin
          quantity:='0';
        end;
        StringGridGoods.Cells[8,i]:='';
        FrmMain.updateStoreHousesGoodsCount(quantity,IntToStr(FrmMain.storeHouseSelectedId),StringGridGoods.Cells[7,i]);
      end;
    end;
   end;
 invoiceIsNew:=False;
 invoiceChanged:=False;
 goodsChanged:=False;
 refreshListOfGoods;
 checkErrors();
end;

procedure TfrmOutputInvoicesElement.btnStoreHousesSelectClick(Sender: TObject);
begin
  frmStoreHouseSelect.ShowModal;
  lblEdtStoreHouse.Text:=FrmMain.storeHouseSelectedTitle;
  invoiceChanged:=True;
  checkErrors();
end;

end.

